package security.config.parser;

import java.util.List;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

import security.core.filter.RBACFilterChainProxy;
import security.debug.RBACLogger;

public class RBACBeanDefinitionParser implements BeanDefinitionParser {
	private final String TAG_NAME = "rbac";

	@Override
	public BeanDefinition parse(Element element, ParserContext pc) {
		if (RBACLogger.debug()) {
			RBACLogger.log("RBACBeanDefinitionParser#parse is called!");
		}
		// construct filters and register to spring
		RBACConfigBuilder configBuilder = new RBACConfigBuilder(element, pc);
		configBuilder.createSessionContextFilter();
		configBuilder.createLogoutFilter();
		configBuilder.createLoginFilter();
		configBuilder.createPrivilegeFilter();
		List<String> ignoreList = configBuilder.parseIgnoreList();
		
		// register a Bean with class of RBACFilterChainProxy using ID of 'RBACSecurityFilterChain', which is required in web.xml
		final Object source = pc.extractSource(element);
		BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(RBACFilterChainProxy.class);
		beanBuilder.getRawBeanDefinition().setSource(source);
		beanBuilder.addPropertyReference("sessionContextFilter", RBACConfigBuilder.SESSION_CONTEXT_FILTER_BEAN_ID);
		beanBuilder.addPropertyReference("logoutFilter", RBACConfigBuilder.LOGOUT_FILTER_BEAN_ID);
		beanBuilder.addPropertyReference("loginFilter", RBACConfigBuilder.LOGIN_FINLTER_BEAN_ID);
		beanBuilder.addPropertyReference("privilegeFilter", RBACConfigBuilder.PRIVILEGE_FILTER_BEAN_ID);
		beanBuilder.addPropertyValue("ignoreList", ignoreList);
		BeanDefinition bean = beanBuilder.getBeanDefinition();
		pc.registerBeanComponent(new BeanComponentDefinition(bean, "RBACSecurityFilterChain"));
		return null;
	}
	
	public String getTagName() {
		return TAG_NAME;
	}

}
